<?php

namespace App\Console\Commands;

use App\Dto\AddContentDTO;
use App\Dto\GetListDTO;
use App\Exceptions\InsertException;
use App\Exceptions\NullRuleException;
use App\Exceptions\URLDuplicateException;
use App\Models\Rule;
use App\Service\ContentService;
use App\Service\ListService;
use Illuminate\Console\Command;


class Crawler extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'crawler:run';

    private bool $debug = false;

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '开始采集网页';

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle(ListService $listService, ContentService $contentService)
    {

        $ruleList = Rule::all();
        foreach ($ruleList as $ruleItem) {
            // 解析当前规则,数据库中存的是一个Json数据
            $rule = json_decode($ruleItem->guize, true);

            $getListDTO = new GetListDTO();
            $getListDTO->setUrl($ruleItem->url);
            $getListDTO->setRule($rule['rule']);
            $getListDTO->setPageRule($rule['page_rule']);
            do {
                $array = $listService->getContentList($getListDTO, $nextPage);
                if ($nextPage) {
                    $getListDTO->setUrl($nextPage);
                }
                foreach ($array as $item) {

                    $addContentDTO = new AddContentDTO($item, $rule['detail_rule'], $ruleItem->leixing);
                    try {
                        $contentService->insert($addContentDTO);
                    } catch (URLDuplicateException $e) {
                        if ($this->debug) {
                            $this->error($addContentDTO->getUrl() . " (URL已存在)");
                        }
                    } catch (NullRuleException $e) {
                        if ($this->debug) {
                            $this->error("采集规则不存在,请配置 main_content_rule");
                        }
                    } catch (InsertException $e) {
                        if ($this->debug) {
                            $this->error("未知异常,插入数据库失败！");
                        }
                    }
                }
            } while ($nextPage);
        }
    }
}
